#include "p2d_force_path.h"

#include "script/scripthelper.h"
#include "util/log.h"		    // log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    // Needs to come in early
#include <math.h>
#include "math/mat4x4.h"

#include "dd/dd_man.h"

#include <cassert>
using namespace part2d;


P2DForcePath::P2DForcePath()
{
    m_Speed		= 1.0f;
	m_Amplitude = 1.0f;
	m_ClosePath = false;
}

P2DForcePath::~P2DForcePath()
{

}
P2DForce*	P2DForcePath::Clone()
{
	P2DForcePath*	pForce = new P2DForcePath();
	pForce->m_Amplitude	= m_Amplitude;
	pForce->m_Speed		= m_Speed;
	pForce->m_ClosePath	= m_ClosePath;
	pForce->m_MinSpeed	= m_MinSpeed;
	return pForce;
}

bool    P2DForcePath::Load(LuaPlus::LuaObject& _LObj)
{
    m_Speed		= script::ScriptHelper::GetTableFloat(_LObj, "Speed", 1.0f);
	m_Amplitude = script::ScriptHelper::GetTableFloat(_LObj, "Amplitude", 1.0f);
	m_ClosePath = script::ScriptHelper::GetTableBool(_LObj, "ClosePath", false);
	m_MinSpeed	= script::ScriptHelper::GetTableFloat(_LObj, "MinSpeed", 0.0f);
    return true;
}

bool	P2DForcePath::RenderDebug(const math::Vec2& GroupCenter)
{
/*    math::Mat4x4    Rot = GroupCenter;
    Rot._41 = Rot._42 = Rot._43 = 0.0f;
    math::Vec2  Dir = Rot.Transform(m_Force);
    dd::Manager::Instance().AddLine(GroupCenter, GroupCenter+Dir,  ColorRGBA(255, 0, 0), true);
  */
	return true;
}

bool	P2DForcePath::MoveParticles(const math::Vec2& GroupCenter, Particle2D* _Particles, unsigned int _usCount, float dt)
{
    for (unsigned int i=0; i<_usCount; i++)
    {
        Particle2D* pPart = &_Particles[i];
        if (pPart->Active)
        {
			// calculate based on current time
			float	Fraction = pPart->Life.GetProgress();
			float	Offset	 = 0.0f;
			if (m_ClosePath)
			{
				Offset = sinf(Fraction * m_Speed) * m_Amplitude * sinf(Fraction*3.14f);
			} else
			{
				Offset = sinf(Fraction * m_Speed) * m_Amplitude;
			}

			if (pPart->Speed < m_MinSpeed)
			{
				pPart->Speed = m_MinSpeed;
			}
			
			pPart->Dir.Normalize();
			pPart->Dir = (pPart->Speed*pPart->Dir)+ (pPart->Speed * Offset * math::Vec2(pPart->Dir.y, -pPart->Dir.x));
			//pPart->Speed = pPart->Dir.Magnitude();
/*			if (pPart->Speed>0)
			{
				pPart->Dir /= pPart->Speed;
			} else
			{
				pPart->Dir  = math::Vec2(1,1);
			}*/
			pPart->Dir.Normalize();
		}
    }

	return true;
}
